﻿using System;
using Logic.Locations;

namespace Logic.Units
{
    /// <summary>
    ///     Супер класс для юнитов
    /// </summary>
    public abstract class UnitTemplate : IUnit, ICloneable
    {
        private int _actualHp;
        private int _count;
        public int HP { get; private set; }

        public int AM { get; private set; }

        public int Damage { get; private set; }

        public byte GoodLuck { get; private set; }

        public UserState State { get; private set; }

        private readonly ICustomRandom _random = new CustomRandom();

        public int Count
        {
            get { return _count; }
            set
            {
                if (_count != value)
                {
                    _count = value;
                    OnChangeCount();
                }
                if (_actualHp == _count*HP) return;

                _actualHp = _count*HP;
                OnChangeActualHp();
            }
        }

        public int ActualHp
        {
            get { return _actualHp; }
            set
            {
                Count = (int) Math.Ceiling(value/(double) HP);
                if (_actualHp == value) return;

                _actualHp = value;
                OnChangeActualHp();
            }
        }

        public int Attack
        {
            get { return (int) (Damage*Count + Damage*_random.GetProcent(GoodLuck)*_random.GetSign()); }
        }

        public int Protection
        {
            get { return (int) (ActualHp + AM*_random.GetProcent(GoodLuck)*_random.GetSign()); }
        }

        public event Action ChangeActualHp;

        protected virtual void OnChangeActualHp()
        {
            Action handler = ChangeActualHp;
            if (handler != null) handler();
        }

        public event Action ChangeCount;

        protected virtual void OnChangeCount()
        {
            Action handler = ChangeCount;
            if (handler != null) handler();
        }

        protected UnitTemplate(int hp, int am, int damage, byte goodLuck, int count = 1,
            UserState state = UserState.Player)
        {
            HP = hp;
            AM = am;
            Damage = damage;
            GoodLuck = goodLuck;
            _count = count;
            _actualHp = hp*_count;
            State = state;
        }

        public void Add(IUnit unit)
        {
            if (unit.GetType() == GetType())
            {
                Count += unit.Count;
            }
            else
            {
                throw new Exception("Обьединение разных типов войск");
            }
        }

        public virtual void GetDone(IUnit enemy)
        {
            ActualHp = Protection - enemy.Attack;
        }

        public override bool Equals(object obj)
        {
            if (obj as IUnit == null) return false;

            return GetType() == (obj as IUnit).GetType() &&
                   ActualHp == (obj as IUnit).ActualHp
                   && State == (obj as IUnit).State;
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        public object Clone()
        {
            return MemberwiseClone();
        }
    }
}